from django.shortcuts import get_object_or_404
from demoapp.models import Student, User

from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status


# serializers
class UserModelSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'


# viewset        
class UserModelViewSet(ModelViewSet):
    serializer_class = UserModelSerializer
    queryset = User.objects.all()

    # 通过 many=True 改造原有的API, 使其支持批量创建
    # 核心就是如果过来的数据是list，则使用many=True
    def get_serializer(self, *args, **kwargs):
        serializer_class = self.get_serializer_class()
        kwargs.setdefault('context', self.get_serializer_context())
        if isinstance(self.request.data, list):
            return serializer_class(many=True, *args, **kwargs)
        else:
            return serializer_class(*args, **kwargs)

    # 使用action自定义方法
    # detail 是针对记录是单条还是多条，这里是自定义批量操作，所以肯定是多条数据，detail=False
    # 自定义批量删除， 方法名就是url的一部分，比如这里的 /v1/user/multi_delete/?ids=1,2,3
    @action(methods=['delete'], detail=False)
    def multi_delete(self, request, *args, **kwargs):
        ids = request.query_params.get('ids', None)
        if not ids:
            return Response(status=status.HTTP_404_NOT_FOUND)

        for id in ids.split(','):
            get_object_or_404(User, id=int(id)).delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

    # 自定义批量更新操作，
    # 更新涉及到 全部 和 局部 更新，所以这里的methods要支持 put(全部)和 patch(局部)
    @action(methods=['put', 'PATCH'], detail=False)
    def multi_update(self, request, *args, **kwargs):
        print("args: ", args, " kwargs: ", kwargs)
        partial = kwargs.pop('partial', None)
        print("partial: ", partial)
        # 报错更新后的结果给前端
        instances = []
        if isinstance(self.request.data, list):
            for item in request.data:
                print(item)
                instance = get_object_or_404(User, id=int(item['id']))
                # partial 允许局部更新
                serializer = super().get_serializer(instance, data=item, partial=partial)
                serializer.is_valid(raise_exception=True)
                serializer.save()
                instances.append(serializer.data)
        else:
            pass
        return Response(instances)
